#ifndef __CONFIG_H__
#define __CONFIG_H__

#define CONFIG_FILE_PATH "config.ini"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>

#include "common.h"

#define MAX_LINE_LEN 1024
#define MAX_LANE_NUM 3

#define TEST_MODE
#define POLE_SENDER

// 定义数据类型枚举
typedef enum {
    CONFIG_INT8,
    CONFIG_INT16,
    CONFIG_INT32,
    CONFIG_DOUBLE,
    CONFIG_STRING,
    CONFIG_INT8_ARRAY,
    CONFIG_INT16_ARRAY,
    CONFIG_INT32_ARRAY,
    CONFIG_DOUBLE_ARRAY,
    CONFIG_STRING_ARRAY,
    CONFIG_INT32_STRUCT,
    CONFIG_DOUBLE_STRUCT,
    CONFIG_IP
} config_type_t;

// 定义配置结构体，包含单值和数组参数
typedef struct {
    // 雷达通信端口配置
    uint16_t radar_server_port;  // 雷达服务器端口（被动接收）
    uint16_t radar_client_port;  // 雷达客户端端口（主动连接）

    // 雷达通信 IP 配置
    uint8_t in_radar_ip[4];   // 来向雷达 IP 地址
    uint8_t out_radar_ip[4];  // 去向雷达 IP 地址

    uint8_t radar_link_mode;  // 雷达连接模式（0:服务端模式,1:客户端模式）

    // 来向雷达距离参数
    uint16_t in_radar_min_distance;  // 来向雷达最小检测距离（单位：0.1m）
    uint16_t in_radar_max_distance;  // 来向雷达最大检测距离（单位：0.1m）
    uint16_t in_radar_offset;        // 来向雷达距离修正偏移值（单位：0.1m）

    // 去向雷达距离参数
    uint16_t out_radar_min_distance;  // 去向雷达最小检测距离（单位：0.1m）
    uint16_t out_radar_max_distance;  // 去向雷达最大检测距离（单位：0.1m）
    uint16_t out_radar_offset;        // 去向雷达距离修正偏移值（单位：0.1m）

    int8_t radar_type;                // 雷达类型（1:北理工，2:森斯泰克）

    // 视频服务器配置
    uint16_t video_server_port;      // 视频服务端监听端口
    char in_video_device_code[64];   // 来向视频设备编号
    char out_video_device_code[64];  // 去向视频设备编号
    int16_t scale_range[4];          // 视频画面识别范围(begin_0,begin_1,end)

    // 视频焦点摄像头 IP 配置
    uint8_t incoming_near_focus_video_ip[4];  // 来向近焦摄像头 IP
    uint8_t incoming_far_focus_video_ip[4];   // 来向远焦摄像头 IP
    uint8_t outgoing_near_focus_video_ip[4];  // 去向近焦摄像头 IP
    uint8_t outgoing_far_focus_video_ip[4];   // 去向远焦摄像头 IP

    double video_center_x_ratio;              // 视频目标的中心点在物体横轴中的比例位置（0.0 ~ 1.0）
    int8_t reference_lane;                    // 计算刻度尺的时候参考车道编号
    int16_t time_diff_ms;                     // 雷达与视频最大时间差（单位：毫秒）

    // 闪马平台服务配置
    uint8_t shanma_server_ip[4];  // 平台服务端 IP
    uint16_t shanma_server_port;  // 平台服务端口

    uint8_t log_switch;           // 日志开关（0=关闭，1=开启）

    // 车道与标尺配置
    uint8_t lane_num;                            // 车道总数量
    uint8_t lane_id[MAX_ROWS];                   // 每个车道的编号
    uint8_t load_ruler_switch;                   // 是否读取标尺，0=不读取，1=读取
    int16_t incoming_graduated_ruler[MAX_COLS];  // 来向标尺刻度数组
    int16_t outgoing_graduated_ruler[MAX_COLS];  // 去向标尺刻度数组

    // 障碍物检测区域配置
    int16_t incoming_obstacle_range[2];  // 来向障碍物区域 [start, end]
    int16_t outgoing_obstacle_range[2];  // 去向障碍物区域 [start, end]
    int16_t event_range;                 // 事件检测范围

    // 车道区域坐标配置（用于目标判断）
    point_t in_lane_coordinate[MAX_ROWS][30];   // 来向车道区域顶点数组
    point_t out_lane_coordinate[MAX_ROWS][30];  // 去向车道区域顶点数组

    // 换道检测配置
    uint16_t change_lane_timeout;  // 换道超时时间（单位：毫秒）

    // 中继区域距离配置（单位：cm）
    uint16_t relay_min_distance;            // 杆内接力检测最小距离
    uint16_t relay_max_distance;            // 杆内接力检测最大距离
    uint16_t candidate_relay_min_distance;  // 杆内候选车道检测最小距离
    uint16_t candidate_relay_max_distance;  // 杆内候选车道检测最大距离

    // 电杆中继距离限制（单位：cm）
    uint16_t pole_relay_max_distance;            // 杆杆接力检测最小距离
    uint16_t pole_relay_min_distance;            // 杆杆接力检测最大距离
    uint16_t pole_candidate_relay_min_distance;  // 杆杆候选车道检测最小距离
    uint16_t pole_candidate_relay_max_distance;  // 杆杆候选车道检测最大距离

    uint16_t pole_distance;                      // 杆与杆之间距离

    int8_t need_fusion;                          // 是否需要雷达与视频融合（0=不融合，1=融合）

    // 调试开关
    uint8_t video_debug;         // 视频调试开关
    uint8_t struct_debug;        // 结构体调试开关
    uint8_t radar_debug;         // 雷达调试开关
    uint8_t fusion_debug;        // 融合调试开关
    uint8_t event_debug;         // 事件调试开关

    char upload_image_url[128];  // 图片上传地址 URL

    uint8_t need_third_relay;    // 是否需要第三方数据做接力（0=不需要，1=需要）
    uint8_t need_pole_relay;     // 是否需要杆杆接力（0=不需要，1=需要）
    uint8_t need_send_pole;      // 是否需要发送杆杆接力数据（0=不需要，1=需要）
} config_t;

// 扩展映射表结构体：对于数组，size 表示最大元素个数；
// 对于 CONFIG_STRING_ARRAY，elem_size 表示每个字符串元素的缓冲区大小。
typedef struct {
    const char *key;      // 配置文件中的 key
    config_type_t type;   // 数据类型
    size_t offset;        // 对应 config_t 中的字段偏移量
    size_t size;          // 若为单一字符串，则为缓冲区大小；若为数组，表示数组最大元素个数
    size_t count_offset;  // 数组类型时，存储实际个数的字段在 config_t 中的偏移量；非数组类型设为 0
    size_t elem_size;     // 对于 CONFIG_STRING_ARRAY，有效元素缓冲区大小；其他类型为 0
} config_mapping_t;

void default_config(config_t *config);
void read_config(const char *config_name, config_t *config);
int update_config_file(const char *config_filename, const char *key, const void *new_value, int array_length, int struct_field_count);
void print_config(const config_t *config);

extern config_t g_config;

#endif  // !__CONFIG_H__
